#include "notify.h"
#include "ws_constant.h"
#include "base.pb.h"
#include "ws_server_c.h"

#include <functional>
#include <unordered_set>

Notify* Notify::pinstance_ = nullptr;

static std::unordered_set<NotifyWsMessage, hash_fun, mycmp> notify_msg_set;

Notify::Notify() {

}

Notify::~Notify() {

}

Notify* Notify::getInstance() {
    if (pinstance_ == nullptr)
        pinstance_ = new Notify();
        
    return pinstance_;
}

int Notify::handleMessage(WsPacket& ws_packet) {
    log_i("handle notify message, cmd = %d", ws_packet.cmd());

    switch (ws_packet.cmd()) {
        case CMD_NOTIFY_TELE_SET_PARAM:
        removeWsMessage(ws_packet.client_id(), ws_packet.cmd());
        break;
    }

    return 0;
}

int Notify::addWsMessage(WsPacket& ws_packet) {
    NotifyWsMessage notify_ws_message(ws_packet);

    if (notify_msg_set.find(notify_ws_message) == notify_msg_set.end()) {
        log_i("add ws_message cmd = %d, client_id = %s", ws_packet.cmd(), ws_packet.client_id().c_str());
        notify_msg_set.insert(notify_ws_message);
    } else {
        log_i("message exits client_id = %s", ws_packet.client_id().c_str());
    }

    printfWsMessage();

    return 0;
}

int Notify::removeWsMessage(const std::string& ws_client_id, int cmd) {
    for (auto it = notify_msg_set.begin(); it != notify_msg_set.end();) {
        const WsPacket packet = it->getWsMessage();
        if (packet.client_id() == ws_client_id && packet.cmd() == cmd) {
            log_i("remove ws_message cmd = %d, client_id = %s", packet.cmd(), packet.client_id().c_str());
            it = notify_msg_set.erase(it);
            printfWsMessage();
            break;
        } else {
            ++it;
        }
    }

    return 0;
}

int Notify::printfWsMessage() {
    log_i("pritnf ws_message");
    for (auto it = notify_msg_set.begin();it != notify_msg_set.end();++it) {
        it->printMessage();
    }

    return 0;
}

/*
轮询notify_msg_set，如果3次没接受到应答，从集合中删除
*/
int Notify::pollWsMessage() {
    for (auto it = notify_msg_set.begin();it != notify_msg_set.end();) {
        log_i("send_count = %d", it->send_count);
        if (it->send_count <= 3) {
            wsResponsePacket(it->getWsMessage());
            const_cast<NotifyWsMessage&>(*it).addSendCount();
            ++it;
        } else {
            it = notify_msg_set.erase(it);
        }
    }

    printfWsMessage();

    return 0;
}